#include <stdio.h>
#include <string.h>
#define x87_instr_recs  x87_instr_recs5
#define instr_recs  instr_recs5
#define ext_instr_recs  ext_instr_recs5
#include "instr_db.h"
#include "instr_dat.h"


static struct instr_rec instr_desc;
#undef OPER_FMT_REC
#define OPER_FMT_REC(x) #x,

static char *  op_fmt_name[]={
#include "oper_fmt_def.h"
"fmt_none"
};
#undef INSTR_REC
#define INSTR_REC(x) #x,

static char *  instr_index_name[]= {
#include "instr_id_def.h"
"unused"
};

extern bool done[sizeof(instr_index_name)/sizeof(instr_index_name[0])];
int __cdecl  gen_alu_h()
{
	FILE *fp;
	fp = fopen("\\whb\\disasmx86\\isa-simu-core\\alu.h","wt");
	if(fp)
	{
		for(int i=0; i <sizeof (done)/sizeof (done[0]);i++)
		{
			done[i]=0;
		}

		for(int i=0; i <sizeof (instr_recs)/sizeof (instr_recs[0]);i++)
		{
			instr_desc = instr_recs[i];
		if (instr_desc.funit !=alu ) continue;
		if (done[instr_desc.index]) continue;
		done[instr_desc.index]=true;
			//
			//decode operands
			//
		fprintf(fp,(instr_desc.dst!=none)?"unsigned long " :"void");

		if (instr_desc.src2==none)
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned char & cflag);\n",instr_index_name[instr_desc.index]);
		else
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned long op2,unsigned char & cflag);\n",instr_index_name[instr_desc.index]);
				
		
		}
		for(int i=0; i <sizeof (ext_instr_recs)/sizeof (ext_instr_recs[0]);i++)
		{
			instr_desc = ext_instr_recs[i];

			if (instr_desc.funit !=alu ) continue;

			if (done[instr_desc.index]) continue;
			done[instr_desc.index]=true;
			//
			//decode operands
			//
		fprintf(fp,(instr_desc.dst!=none)?"unsigned long " :"void");

		if (instr_desc.src2==none)
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned char & cflag);\n",instr_index_name[instr_desc.index]);
		else
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned long op2,unsigned char & cflag);\n",instr_index_name[instr_desc.index]);
				
		
		
		}





	fclose(fp);
	return 1;
	}

	return 0;

}


int __cdecl  gen_alu_cpp()
{

	

	FILE *fp;
	
	gen_alu_h();
	fp = fopen("\\whb\\disasmx86\\isa-simu-core\\alu.cpp","wt");
	if(fp)
	{

		fprintf(fp,"#pragma warning  (disable:4101)\n");		

		fprintf(fp,"#include \"alu.h\"\n"
			       "#include \"cpu-util.h\"\n"
				   "#include \"uop.h\"\n"
				   "#include \"cpu.h\"\n"


				   "#undef INSTR_REC\n"
				   "#define INSTR_REC(x) x,\n\n"

				   "enum INSTR_ID {\n"
				   "#include \"instr_id_def.h\"\n"
 				   "unused\n"
				   "};\n\n"
				   "extern CCPU cpu;\n"

			       "\n\n");
			for(int i=0; i <sizeof (done)/sizeof (done[0]);i++)
		{
			done[i]=0;
		}
		for(int i=0; i <sizeof (instr_recs)/sizeof (instr_recs[0]);i++)
		{
			instr_desc = instr_recs[i];
			if (instr_desc.index==unused  ) continue;
			
			if (instr_desc.funit !=alu ) continue;
				if (done[instr_desc.index]) continue;
				done[instr_desc.index]=true;
			//
			//decode operands
			//
			fprintf(fp,(instr_desc.dst!=none)?"unsigned long " :"void");

		if (instr_desc.src2==none)
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned char & cflag)\n",instr_index_name[instr_desc.index]);
		else
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned long op2,unsigned char & cflag)\n",instr_index_name[instr_desc.index]);
				
			fprintf(fp,"\n{\n");


			fprintf(fp,(instr_desc.dst!=none)?"unsigned long  result;\n\n\n\nreturn result;\n" :"\n\n\nreturn;\n");
		
		
			fprintf(fp,"}\n");
		}
		for(int i=0; i <sizeof (ext_instr_recs)/sizeof (ext_instr_recs[0]);i++)
		{
			instr_desc = ext_instr_recs[i];
			if (instr_desc.index==unused  ) continue;
			
			if (instr_desc.funit !=alu ) continue;

			if (done[instr_desc.index]) continue;
			done[instr_desc.index]=true;
			//
			//decode operands
			//
		fprintf(fp,(instr_desc.dst!=none)?"unsigned long " :"void");

		if (instr_desc.src2==none)
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned char & cflag)\n",instr_index_name[instr_desc.index]);
		else
				fprintf(fp," alu_%s(int op_size,unsigned long  op1,unsigned long op2,unsigned char & cflag)\n",instr_index_name[instr_desc.index]);
				
		fprintf(fp,"\n{\n");

			fprintf(fp,(instr_desc.dst!=none)?"unsigned long  result;\n\n\n\nreturn result;\n" :"\n\n\nreturn;\n");
	
	
		fprintf(fp,"}\n");
		}
		//
		// generates stub
		//

		fprintf(fp,"void alu_exec(UOP uop)\n"
				   "{\n"
				   "unsigned char cflag=cpu.get_cflag();\n"
				   "unsigned long result;\n\n"
				   "switch(uop.sub_op)\n"
				   "{\n");
		for(int i=0; i <sizeof (done)/sizeof (done[0]);i++)
		{
			done[i]=0;
		}
		for(int i=0; i <sizeof (instr_recs)/sizeof (instr_recs[0]);i++)
		{
			instr_desc = instr_recs[i];
			if (instr_desc.index==unused  ) continue;
			
			if (instr_desc.funit !=alu ) continue;
			if (done[instr_desc.index]) continue;
			done[instr_desc.index]=true;
			//
			//decode operands
			//
			fprintf(fp,"case %s:\n",instr_index_name[instr_desc.index]);
			if (instr_desc.src2==none)
					fprintf(fp,"if(!uop.src[0].va)__asm int 3;\n");
			else
					fprintf(fp,"if(!uop.src[0].va||!uop.src[1].va)__asm int 3;\n");

			fprintf(fp,(instr_desc.dst!=none)?"result= " :"");
			if (instr_desc.src2==none)
					fprintf(fp,"alu_%s( uop.op_size, uop.src[0].u.value, cflag);\n",instr_index_name[instr_desc.index]);
			else
					fprintf(fp,"alu_%s( uop.op_size,  uop.src[0].u.value,uop.src[1].u.value,cflag);\n",instr_index_name[instr_desc.index]);
					
			fprintf(fp,"\nbreak;\n");
		}
		for(int i=0; i <sizeof (ext_instr_recs)/sizeof (ext_instr_recs[0]);i++)
		{
			instr_desc = ext_instr_recs[i];
			if (instr_desc.index==unused  ) continue;
			
			if (instr_desc.funit !=alu ) continue;
			if (done[instr_desc.index]) continue;
			done[instr_desc.index]=true;
			//
			//decode operands
			//
			fprintf(fp,"case %s:\n",instr_index_name[instr_desc.index]);
			if (instr_desc.src2==none)
					fprintf(fp,"if(!uop.src[0].va)__asm int 3;\n");
			else
					fprintf(fp,"if(!uop.src[0].va||!uop.src[1].va)__asm int 3;\n");
			
			fprintf(fp,(instr_desc.dst!=none)?"result= " :"");
			if (instr_desc.src2==none)
					fprintf(fp,"alu_%s( uop.op_size, uop.src[0].u.value, cflag);\n",instr_index_name[instr_desc.index]);
			else
					fprintf(fp,"alu_%s( uop.op_size,  uop.src[0].u.value,uop.src[1].u.value,cflag);\n",instr_index_name[instr_desc.index]);
					
			fprintf(fp,"\nbreak;\n");
		}
		fprintf(fp,"default:\n\n"
			       "     __asm int 3;\n"
				   "}\n"
				   "//\n"
				   "//set back result\n"
				   "//\n"
				   "if(uop.dst!=-1)\n"
				   "       cpu.set_reg(uop.dst,result);\n"
				   "cpu.set_cflag(cflag);\n"
				   "\n}\n");


		fclose(fp);
	}
	return 0;

}
int __cdecl  gen_alu_cpp1()
{

	

	FILE *fp;
	
	fp = fopen("\\whb\\disasmx86\\isa-simu-core\\alu.cpp","wt");
	if(fp)
	{

		fprintf(fp,"#pragma warning  (disable:4101)\n");		

		fprintf(fp,"#include \"alucore.h\"\n"
						   "#include \"uop.h\"\n"
				   "#include \"cpu.h\"\n"


				   "#undef INSTR_REC\n"
				   "#define INSTR_REC(x) x,\n\n"

				   "enum INSTR_ID {\n"
				   "#include \"instr_id_def.h\"\n"
 				   "unused\n"
				   "};\n\n"
				   "extern CCPU cpu;\n"

			       "\n\n");
		//
		// generates stub
		//

		fprintf(fp,"void alu_exec(UOP uop)\n"
				   "{\n"
				   "unsigned short cflag=cpu.get_cflag();\n"
				   "unsigned long result;\n\n"
				   "switch(uop.sub_op)\n"
				   "{\n");
		for(int i=0; i <sizeof (done)/sizeof (done[0]);i++)
		{
			done[i]=0;
		}
		for(int i=0; i <sizeof (instr_recs)/sizeof (instr_recs[0]);i++)
		{
			instr_desc = instr_recs[i];
			if (instr_desc.index==unused  ) continue;
			
			if (instr_desc.funit !=alu ) continue;
			if (done[instr_desc.index]) continue;
			done[instr_desc.index]=true;
			//
			//decode operands
			//
			fprintf(fp,"case %s:\n",instr_index_name[instr_desc.index]);

			if (instr_desc.src2==none)
					fprintf(fp,"if(!uop.src[0].va)__asm int 3;\n");
			else
					fprintf(fp,"if(!uop.src[0].va||!uop.src[1].va)__asm int 3;\n");

			fprintf(fp,(instr_desc.dst!=none)?"result= " :"");

			if (instr_desc.src1==cflag||instr_desc.src1==none)
				fprintf(fp,"alu_%s( cflag);\n",instr_index_name[instr_desc.index]);
			
			else if (instr_desc.src2==none)
					fprintf(fp,"alu_%s( cflag, uop.src[0].u.value, uop.op_size);\n",instr_index_name[instr_desc.index]);
			else
					fprintf(fp,"alu_%s( cflag,  uop.src[0].u.value,uop.src[1].u.value,uop.op_size);\n",instr_index_name[instr_desc.index]);
					
			fprintf(fp,"\nbreak;\n");
		}
		for(int i=0; i <sizeof (ext_instr_recs)/sizeof (ext_instr_recs[0]);i++)
		{
			instr_desc = ext_instr_recs[i];
			if (instr_desc.index==unused  ) continue;
			
			if (instr_desc.funit !=alu ) continue;
			if (done[instr_desc.index]) continue;
			done[instr_desc.index]=true;
			//
			//decode operands
			//
			fprintf(fp,"case %s:\n",instr_index_name[instr_desc.index]);
			if (instr_desc.src2==none)
					fprintf(fp,"if(!uop.src[0].va)__asm int 3;\n");
			else
					fprintf(fp,"if(!uop.src[0].va||!uop.src[1].va)__asm int 3;\n");
			
			fprintf(fp,(instr_desc.dst!=none)?"result= " :"");
			if (instr_desc.src1==cflag||instr_desc.src1==none)
				fprintf(fp,"alu_%s( cflag);\n",instr_index_name[instr_desc.index]);
			else if (instr_desc.src2==none)
					fprintf(fp,"alu_%s( cflag, uop.src[0].u.value, uop.op_size);\n",instr_index_name[instr_desc.index]);
			else
					fprintf(fp,"alu_%s( cflag,  uop.src[0].u.value,uop.src[1].u.value,uop.op_size);\n",instr_index_name[instr_desc.index]);
					
			fprintf(fp,"\nbreak;\n");
		}
		fprintf(fp,"default:\n\n"
			       "     __asm int 3;\n"
				   "}\n"
				   "//\n"
				   "//set back result\n"
				   "//\n"
				   "if(uop.dst!=-1)\n"
				   "       cpu.set_reg(uop.dst,result);\n"
				   "cpu.set_cflag(cflag);\n"
				   "\n}\n");


		fclose(fp);
	}
	return 0;

}
/*

                  TABLE 1
    ______________________________________
    x86 Fast Path, Double Dispatch, and MROM Instructions
    X86 Instruction   Instruction Category
    ______________________________________
    AAA               MROM
    AAD               MROM
    AAM               MROM
    AAS               MROM
    ADC               fast path
    ADD               fast path
    AND               fast path
    ARPL              MROM
    BOUND             MROM
    BSF               fast path
    BSR               fast path
    BSWAP             MROM
    BT                fast path
    BTC               fast path
    BTR               fast path
    BTS               fast path
    CALL              fast path/double dispatch
    CBW               fast path
    CWDE              fast path
    CLC               fast path
    CLD               fast path
    CLI               MROM
    CLTS              MROM
    CMC               fast path
    CMP               fast path
    CMPS              MROM
    CMPSB             MROM
    CMPSW             MROM
    CMPSD             MROM
    CMPXCHG           MROM
    CMPXCHG8B         MROM
    CPUID             MROM
    CWD               MROM
    CWQ               MROM
    DDA               MROM
    DAS               MROM
    DEC               fast path
    DIV               MROM
    ENTER             MROM
    HLT               MROM
    IDIV              MROM
    IMUL              double dispatch
    IN                MROM
    INC               fast path
    INS               MROM
    INSB              MROM
    INSW              MROM
    INSD              MROM
    INT               MROM
    INTO              MROM
    INVD              MROM
    INVLPG            MROM
    IRET              MROM
    IRETD             MROM
    Jcc               fast path
    JCXZ              double dispatch
    JECXZ             double dispatch
    JMP               fast path
    LAHF              fast path
    LAR               MROM
    LDS               MROM
    LES               MROM
    LFS               MROM
    LGS               MROM
    LSS               MROM
    LEA               fast path
    LEAVE             double dispatch
    LGDT              MROM
    LIDT              MROM
    LLDT              MROM
    LMSW              MROM
    LODS              MROM
    LODSB             MROM
    LODSW             MROM
    LODSD             MROM
    LOOP              double dispatch
    LOOPcond          MROM
    LSL               MROM
    LTR               MROM
    MOV               fast path
    MOVCC             fast path
    MOV.CR            MROM
    MOV.DR            MROM
    MOVS              MROM
    MOVSB             MROM
    MOVSW             MROM
    MOVSD             MROM
    MOVSX             fast path
    MOVZX             fast path
    MUL               double dispatch
    NEG               fast path
    NOP               fast path
    NOT               fast path
    OR                fast path
    OUT               MROM
    OUTS              MROM
    OUTSB             MROM
    OUTSW             MROM
    OUTSD             MROM
    POP               double dispatch
    POPA              MROM
    POPAD             MROM
    POPF              MROM
    POPFD             MROM
    PUSH              fast path/double dispatch
    PUSHA             MROM
    PUSHAD            MROM
    PUSHF             fast path
    PUSHFD            fast path
    RCL               MROM
    RCR               MROM
    ROL               fast path
    ROR               fast path
    RDMSR             MROM
    REP               MROM
    REPE              MROM
    REPZ              MROM
    REPNE             MROM
    REPNZ             MROM
    RET               double dispatch
    RSM               MROM
    SAHF              fast path
    SAL               fast path
    SAR               fast path
    SHL               fast path
    SHR               fast path
    SBB               fast path
    SCAS              double dispatch
    SCASB             MROM
    SCASW             MROM
    SCASD             MROM
    SETcc             fast path
    SGDT              MROM
    SIDT              MROM
    SHLD              MROM
    SHRD              MROM
    SLDT              MROM
    SMSW              MROM
    STC               fast path
    STD               fast path
    STI               MROM
    STOS              MROM
    STOSB             MROM
    STOSW             MROM
    STOSD             MROM
    STR               MROM
    SUB               fast path
    TEST              fast path
    VERR              MROM
    VERW              MROM
    WBINVD            MROM
    WRMSR             MROM
    XADD              MROM
    XCHG              MROM
    XLAT              fast path
    XLATB             fast path
    XOR               fast path

*/

